//前端是无法直接读取文件 操作文件 （node是使用在服务端的）
//对文件和前端传递的数据进行处理
//进制数据 所有内容都是以2进制存储的,数据都是以2进制形式来表现的

//最终数据都是以2进制来存储的 所以会出现不精准的情况
//二进制 十进制的区别 10进制中最大的是9 2进制中最大的是9 2进制中最大数是1
//我们以字节的单位来存储数据 8位->1个字节(计算机展现给我们的最小单位) 1024字节 -> 1k  1024k ->1M

//其他进制中如何转化成10进制 当前的位的值*进制^当前所在位 ,把每一位进行相加
let sum= [];
for(let i=0;i<8;i++){
    sum +=Math.pow(2,i);
}
//每个字节最大255，16进制 8进制
console.log(sum);

//将一个10进制转成2进制？取余数导着读 就可以获取到对应的进制
console.log("转成数字", parseInt('101', 2));//parseInt把任何进制转化成10进制
//二进制 0x16进制十六进制 ob二进制
console.log("转成字符串",(0x16).toString(2));//将任何进制转化成任意进制（返回字符串）

//小数也要转成二进制存储（内存中存储方式都是二进制）
//10进制中0.5 是2进制中的多少？ 10-》0.5 2=》0.1
//10进制中的0.5就是 2进制中的0.1 乘2去整法可以将小数一个小数转成2进制数
//0.1*2 = 0.2 0
//0.2*2 = 0.4 0
//0.4*2 = 0.8 0
//0.8*2 = 1.6 1
//0.6*2 = 1.2 1
//0.2*2 = 0.4 0
console.log(0.1+0.2);
//进制转换问题？0.2+0.2那如果哦出现了精度问题你要怎么解决？
//js没有把小数转成二进制的方法

//在服务端 我们需要一个东西来标识内存。但是不能是字符串，因为字符串无法标识图片
//node中用Buffer来标识内存的数据 他把内容转换成了16进制来显示（16进制比较短）
//10进制 -> 255 0b11111111 2进制 0xff 16进制 buffer每个字节的取值范围就是0-0xff

//node中的buffer可以和字符串任意转换（可能出现乱码）
//编码规范ASCII（美国人）-> GB18030/GBK -> unicode -> UTF8 编码的发展史

//单字节（因为字母，符号...都是一个字节）
//中国为了能标识自己(gb2312/GB18030/GBK) 对于文字来说是由2个字节组成
//unicode希望统一所有编码->可变字节长度 没有统一成功。将范围转成了标准（utf是实现unicode实现方式）
//utf组织解决了这个问题（utf8编码 一个汉字有3个字节组成）
//http://www.zhufengpeixun.com/grow/html/8.Encoding.html

//全部同意成utf8 node不支持gbk 只支持utf8
//Buffer代表的是内存 内存是一段“固定的空间”，产生的内存是固定大小 不能随意添加
//扩容的概念，需要动态创建一个新的内容，把内容迁移过去

//npm install @type可以支持提示（仅仅是安装了ts提示而已 为了方便）
//最小单位就是字节
const buffer1 = Buffer.alloc(5);//限定长度
console.log(buffer1[0]);//像数组（但是和数组有区别），数组可以拓展 buffer不能拓展 可以用索引取值(取出来是10进制)，没有forEach...

//此方法用的非常少 我们不会直接直接填16进制
const buffer2 = Buffer.from([0x24,0x255,0x64]);//超过255 会取余
console.log("buffer2",buffer2);

let buffer3 = Buffer.from("珠峰");//6个字节
console.log(buffer3);

//一般情况下，我们会alloc来声明一个buffer,或者把字符串转成buffer使用
//后台获取的数据都是buffer,包括后面的文件操作都是buffer形式

//buffer的使用 无论是2进制还是16进制他们表示的东西都是一样的

//base64"编码",在后期使用的过程中非常多（base64没有加密功能）所有人都知道这个规范
//加密 -》 解密 （md5不可逆不是加密算法|要么撞库解回来）
//base64 字符串可以放到任何路径的链接里（可以减少请求的发送）文件大小会变大（如果采用base65 他的缓存会依赖文件），base64转换完毕后会比之前的文件大1/3


const r = Buffer.from('珠').toString('base64');//可以调用tostring方法转成指定的编码
console.log(r);//54+g 4个字节比原来3大了1/3

//base64的来源就是将每个字节都转成小于64的值
console.log(0xe7.toString(2));
console.log(0x8f.toString(2));
console.log(0xa0.toString(2));

//11100111 1000111 10100000  3*8 => 6*4
//111001 111000 111110 100000 


//toSting可以转成我想要的编码
//回到buffer toSting('utf8'/'base64')

//slice
/* let buffer4 = Buffer.from([1,2,3,4]);//内部存的是引用地址
let sliceBuffer = buffer4.slice(0,1);//原Buffer上进行操作
sliceBuffer[0] = 100;//内存就是引用地址 引用地址截取出来 是会变的
console.log(buffer4); 
*/
/* let arr = [[1],2,3,4];
let newArr = arr.slice(0,1);//二维数组的slice 相当于buffer,数组中存的是引用地址 slice是浅拷贝
newArr[0][0] = 100;
console.log(arr); */
//实现非递归版的深拷贝

//copy 可以将buffer的数据拷贝到另一个buffer上（一般用不到 contact是基于buffer的）
//alloc from slice（截取） copy(小buffer拼接) concat indexOf  isBuffer buffer.length
/* 
Buffer.prototype.copy = function (targetBuffer, targetStart, sourceStart=0,sourceEnd = this.length) {
    for(let i=sourceStart;i<sourceEnd;i++){
        targetBuffer[targetStart++] = this[i]
    }
}

let bigBuffer = Buffer.alloc(12);// === new Buffer(12)
buf0.copy(bigBuffer,6,0,6);
buf1.copy(bigBuffer, 0,0,3);
buf2.copy(bigBuffer, 3);//默认后边两个参数不用传递
console.log(bigBuffer.toString()); 
*/

//concat
let buf0 = Buffer.from("架构");
let buf1 = Buffer.from("珠");
let buf2 = Buffer.from("峰");
Buffer.concat = function (bufferList,length = bufferList.reduce((a,b)=>a+b.length,0)) {
    let bigBuffer = Buffer.alloc(length);
    let offset = 0;
    bufferList.forEach(buf=>{
        buf.copy(bigBuffer,offset);
        offset += buf.length
    })
    return bigBuffer
}
//http数据是分包传递的，把每断数据进行拼接

//console.log(Buffer.concat([buf1,buf2,bf0],100));